package pl.agh.convexhulltutor.algorithms;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import pl.agh.convexhulltutor.gui.DrawPanel;
import pl.agh.convexhulltutor.structures.Line;
import pl.agh.convexhulltutor.structures.Point;

public class BruteForceAlgorithm extends Algorithm {
	private int i = 0;
	private int j = 1;
	private int k = 2;

	private int stepType = 0;

	public BruteForceAlgorithm(DrawPanel drawPanel) {
		super(drawPanel);
	}

	@Override
	public void execute(List<Point> points, List<Line> lines) {
		if (maxStep == -1 || currentStep < maxStep) {
			Point point1 = points.get(i);
			Point point2 = points.get(j);
			Point point3 = points.get(k);

			switch (stepType++ % 4) {
			case 0:
				point1.setColor(Point.VERTEX_COLOR);
				point2.setColor(Point.VERTEX_COLOR);
				point3.setColor(Point.VERTEX_COLOR);
				break;
			case 1:
				lines.add(new Line(point1, point2));
				lines.add(new Line(point2, point3));
				lines.add(new Line(point3, point1));
				break;
			case 2:
				if (getDeterminantSign(point1, point2, point3) != 0) {
					for (Point pointOfInterest : points) {
						if (isPointInsideTriangle(pointOfInterest, point1,
								point2, point3)) {
							pointOfInterest
									.setColor(Point.NON_CONVEX_HULL_COLOR);
						}
					}
				} else {
					List<Point> collinearPoints = Arrays.asList(new Point[] {
							point1, point2, point3 });
					Collections.sort(collinearPoints);
					collinearPoints.get(1)
							.setColor(Point.NON_CONVEX_HULL_COLOR);
				}
				break;
			case 3:
				if (point1.getColor() == Point.VERTEX_COLOR) {
					point1.setPreviousColor();
				}
				if (point2.getColor() == Point.VERTEX_COLOR) {
					point2.setPreviousColor();
				}
				if (point3.getColor() == Point.VERTEX_COLOR) {
					point3.setPreviousColor();
				}
				lines.clear();
				if ((i + 3) % points.size() == 0
						&& (j + 2) % points.size() == 0
						&& (k + 1) % points.size() == 0) {
					maxStep = currentStep + 1;
				} else if ((j + 2) % points.size() == 0
						&& (k + 1) % points.size() == 0) {
					i++;
					j = i + 1;
					k = j + 1;
				} else if ((k + 1) % points.size() == 0) {
					j++;
					k = j + 1;
				} else {
					k++;
				}
				break;
			}
		} else {
			for (Point point : points) {
				if (point.getColor() != Point.NON_CONVEX_HULL_COLOR) {
					point.setColor(Point.CONVEX_HULL_COLOR);
				}
			}
		}
	}
}
